package cn.song.freight.domain.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 策略区域定价数据对象 (DO)
 * <pre>
 * 该实体类代表运费策略的定价配置。
 * V3版本调整：独立的定价配置，可复用于多个区域。
 * 支持为每个策略配置多套不同的定价方案。
 *
 * 业务场景：
 * - 同一个策略可以有多套定价配置（如：标准定价、偏远地区定价）
 * - 一套定价配置可以应用于多个区域
 * - 配合重量区间规则和区域映射实现完整的定价体系
 *
 * 数据关系：
 * - 与freight_strategy表建立多对一关系
 * - 通过pricing_area_mapping表与area表建立多对多关系
 * - 与weight_segment_rule表建立一对多关系
 *
 * 约束规则：
 * - 所有价格字段必须为正数
 * - 首重和续重重量不能为负数
 * - 定价配置名称在同一策略下应唯一
 *
 * @author SongRenShuo
 * @version 3.0.0
 * @since 2025-08-25
 * </pre>
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("strategy_area_pricing")
@ApiModel(description = "策略区域定价数据对象")
public class StrategyAreaPricingDO {

    /**
     * 主键ID
     */
    @TableId(type = IdType.AUTO)
    @ApiModelProperty(value = "主键ID")
    private Long id;

    /**
     * 运费策略ID
     * 关联freight_strategy表的主键
     */
    @TableField("strategy_id")
    @ApiModelProperty(value = "运费策略ID", required = true)
    private Long strategyId;

    /**
     * 定价配置名称
     * 用于标识和区分不同的定价配置
     * 示例："华东标准定价"、"偏远地区定价"
     */
    @TableField("name")
    @ApiModelProperty(value = "定价配置名称（如：华东标准定价）", required = true)
    private String name;

    /**
     * 定价配置描述
     * 详细说明该定价配置的适用场景和特点
     */
    @TableField("description")
    @ApiModelProperty(value = "定价配置描述说明")
    private String description;

    /**
     * 首重重量（kg）
     * 该区域专用的首重重量配置
     * 不能为负数，支持小数点后4位精度
     */
    @TableField("first_weight_kg")
    @ApiModelProperty(value = "首重重量（kg）", required = true, example = "1.0000")
    private BigDecimal firstWeightKg;

    /**
     * 首重资费（元）
     * 该区域专用的首重费用配置
     * 不能为负数，支持小数点后4位精度
     */
    @TableField("first_weight_fee")
    @ApiModelProperty(value = "首重资费（元）", required = true, example = "10.0000")
    private BigDecimal firstWeightFee;

    /**
     * 续重重量（kg）
     * 该区域专用的续重计费单位
     * 不能为负数，支持小数点后4位精度
     */
    @TableField("additional_weight_kg")
    @ApiModelProperty(value = "续重重量（kg）", required = true, example = "0.5000")
    private BigDecimal additionalWeightKg;

    /**
     * 续重资费（元）
     * 该区域专用的续重费用配置
     * 不能为负数，支持小数点后4位精度
     */
    @TableField("additional_weight_fee")
    @ApiModelProperty(value = "续重资费（元）", required = true, example = "3.0000")
    private BigDecimal additionalWeightFee;
    /**
     * 抛重比（如6000表示1m³按6000kg计费），0表示不启用体积重
     */
    @TableField("volumetric_weight_ratio")
    @ApiModelProperty(value = "抛重比（如6000表示1m³按6000kg计费），0表示不启用体积重", required = true, example = "6000")
    private BigDecimal volumetricWeightRatio;

    /**
     * 创建时间
     * 记录配置的创建时间，由数据库自动填充
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 最后更新时间
     * 记录配置的最后修改时间，在插入和更新时自动填充
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(value = "最后更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    /**
     * 操作人
     * 记录创建或最后修改该配置的用户
     */
    @TableField("operator")
    @ApiModelProperty(value = "操作人", example = "admin")
    private String operator;

    // ================================
    // 业务方法
    // ================================

    /**
     * 检查定价配置是否有效
     * @return true-有效，false-无效
     */
    public boolean isValid() {
        return strategyId != null && strategyId > 0
                && name != null && !name.trim().isEmpty()
                && firstWeightKg != null && firstWeightKg.compareTo(BigDecimal.ZERO) >= 0
                && firstWeightFee != null && firstWeightFee.compareTo(BigDecimal.ZERO) >= 0
                && additionalWeightKg != null && additionalWeightKg.compareTo(BigDecimal.ZERO) >= 0
                && additionalWeightFee != null && additionalWeightFee.compareTo(BigDecimal.ZERO) >= 0
                && volumetricWeightRatio != null && volumetricWeightRatio.compareTo(BigDecimal.ZERO) >= 0;
    }

    /**
     * 获取定价配置的显示描述
     * @return 定价描述字符串
     */
    public String getPricingDescription() {
        if (!isValid()) {
            return "无效配置";
        }
        return String.format("首重%skg/%s元，续重%skg/%s元，抛重比%s",
                firstWeightKg, firstWeightFee,
                additionalWeightKg, additionalWeightFee,volumetricWeightRatio);
    }

    /**
     * 复制创建新的定价配置（不包含ID和时间字段）
     * @return 新的定价配置对象
     */
    public StrategyAreaPricingDO copyForNew() {
        StrategyAreaPricingDO copy = new StrategyAreaPricingDO();
        copy.setStrategyId(this.strategyId);
        copy.setName(this.name);
        copy.setDescription(this.description);
        copy.setFirstWeightKg(this.firstWeightKg);
        copy.setFirstWeightFee(this.firstWeightFee);
        copy.setAdditionalWeightKg(this.additionalWeightKg);
        copy.setAdditionalWeightFee(this.additionalWeightFee);
        copy.setVolumetricWeightRatio(this.volumetricWeightRatio);
        copy.setOperator(this.operator);
        return copy;
    }
}
